package fr.obsmip.sedoo.client.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import fr.obsmip.sedoo.client.message.Message;
import fr.obsmip.sedoo.client.ui.map.MarkerConstants;
import fr.obsmip.sedoo.client.ui.map.MarkerDefinition;
import fr.obsmip.sedoo.client.ui.misc.GeoSummaryMap;
import fr.obsmip.sedoo.shared.domain.AbstractGeoSummaryDTO;

public class GeoSummaryViewImpl extends AbstractSection implements GeoSummaryView, ClickHandler {

	@UiField GeoSummaryMap summaryMap;
	
	HashMap<String, MarkerDefinition> markerMap = new HashMap<String, MarkerDefinition>();
	
	Iterator<MarkerDefinition> markerIterator;

	@UiField VerticalPanel observatoryPanel;
	
	@UiField CheckBox experimentalSites;
	
	@UiField CheckBox datasets;

	private Presenter presenter;

	private List<CheckBox> observatoryBoxes = new ArrayList<CheckBox>();

	private static GeoSummaryViewImplUiBinder uiBinder = GWT
			.create(GeoSummaryViewImplUiBinder.class);

	private List<String> loadedLayers = new ArrayList<String>();

	private CheckBox all;

	interface GeoSummaryViewImplUiBinder extends UiBinder<Widget, GeoSummaryViewImpl> {
	}

	public GeoSummaryViewImpl() {
		super();
		initWidget(uiBinder.createAndBindUi(this));
		applyCommonStyle();
		experimentalSites.addClickHandler(this);
		datasets.addClickHandler(this);
		summaryMap.displayExperimentalSites(experimentalSites.getValue());
		summaryMap.displayDataSets(datasets.getValue());
	}

	@Override
	public void setObservatoryNames(List<String> observatoryList) 
	{
		if (observatoryBoxes.size()==0)
		{
			observatoryPanel.clear();
			//observatoryBoxes.clear();
			all = new CheckBox(Message.INSTANCE.all());
			all.setName(Message.INSTANCE.all());
			observatoryPanel.add(getCheckBoxPanel(all, "white"));
			all.addClickHandler(this);
			

			Iterator<String> iterator = observatoryList.iterator();
			while (iterator.hasNext()) {
				String name = iterator.next();
				MarkerDefinition marker = getNextMarker();
				markerMap.put(name, marker);
				CheckBox aux = new CheckBox(name);
				aux.setName(name);
				aux.addClickHandler(this);
				observatoryPanel.add(getCheckBoxPanel(aux, marker.getColor()));
				observatoryBoxes.add(aux);
			}
		}
	}

	private HorizontalPanel getCheckBoxPanel(CheckBox aux, String color) 
	{
		HorizontalPanel panel = new HorizontalPanel();
		Label coloredBlock = new Label("-");
		coloredBlock.getElement().getStyle().setProperty("background", color);
		coloredBlock.getElement().getStyle().setProperty("color", color);
		coloredBlock.getElement().getStyle().setProperty("width", "8px");
		panel.add(coloredBlock);
		panel.getElement().getStyle().setProperty("leftBorder", "5px solid "+color+";");
		panel.add(aux);
		return panel;
	}

	@Override
	public void onClick(ClickEvent event) {

	if (event.getSource()== experimentalSites)
	{
		summaryMap.displayExperimentalSites(experimentalSites.getValue());
	}
	else if (event.getSource()== datasets)
	{
		summaryMap.displayDataSets(datasets.getValue());
	}

	else if (event.getSource() instanceof CheckBox)
		{
			CheckBox aux = (CheckBox) event.getSource();
			if (aux.getName().compareTo(Message.INSTANCE.all())==0)
			{
				if (aux.getValue()== true)
				{
					Iterator<CheckBox> iterator = observatoryBoxes.iterator();
					List<String> missingObservatories = new ArrayList<String>();
					while (iterator.hasNext()) 
					{
						CheckBox checkBox = (CheckBox) iterator.next();
						checkBox.setValue(true);
						String observatoryName = checkBox.getName();
						if (loadedLayers.contains(observatoryName))
						{
							summaryMap.showLayer(observatoryName);
						}
						else
						{
							missingObservatories.add(observatoryName);
						}
					}
					if (missingObservatories.isEmpty() == false)
					{
						presenter.loadAllGeoSummaries(missingObservatories);
					}
				}
				else
				{
					Iterator<CheckBox> iterator = observatoryBoxes.iterator();
					while (iterator.hasNext()) 
					{
						CheckBox checkBox = (CheckBox) iterator.next();
						checkBox.setValue(false);
						String observatoryName = checkBox.getName();
						if (loadedLayers.contains(observatoryName))
						{
							summaryMap.hideLayer(observatoryName);
						}
					}
				}
			}
			else
			{
				String observatoryName = aux.getName();
				if (aux.getValue() == true)
				{
					if (loadedLayers.contains(observatoryName))
					{
						summaryMap.showLayer(observatoryName);
					}
					else
					{
						getPresenter().loadGeoSummaries(observatoryName);
					}
				}
				else
				{
					summaryMap.hideLayer(observatoryName);
					all.setValue(false);
				}
			}
		}

	}

	public void displayGeoSummaries(List<? extends AbstractGeoSummaryDTO> summaries, String observatoryName)
	{
		loadedLayers.add(observatoryName);
		Iterator<? extends AbstractGeoSummaryDTO> iterator = summaries.iterator();
		while (iterator.hasNext()) {
			summaryMap.addMarkersForObservatory(iterator.next(), observatoryName, markerMap.get(observatoryName));
		}
	}

	@Override
	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
		if (summaryMap != null)
		{
			summaryMap.setPresenter(presenter);
		}
	}

	public Presenter getPresenter() {
		return presenter;
	}

	@Override
	public void reset() {
		//		if (summaryMap != null)
		//		{
		//			summaryMap.clear();
		//		}
	}

	@Override
	public void ensureVisible() {
		summaryMap.ensureVisible();
	}

	protected MarkerDefinition getNextMarker()
	{
		if ((markerIterator == null) || (markerIterator.hasNext() == false))
		{
			markerIterator = MarkerConstants.markerDefinitions.iterator();
		}
		return markerIterator.next();
	}
	
	@Override
	public void onResize() {
		super.onResize();
		summaryMap.onResize();
	}
	
}
